package jp.co.dailyReport.expense.action;

import java.io.IOException;
import java.util.Calendar;
import java.util.Vector;
import javax.servlet.ServletException;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.validator.DynaValidatorForm;
import jp.co.dailyReport.DataUnavailableException;
import jp.co.dailyReport.Utilities;
import jp.co.dailyReport.staff.Staff;
import jp.co.dailyReport.expense.ExpenseManufacturingCondition;
import jp.co.dailyReport.expense.ExpenseManufacturingResult;
import jp.co.dailyReport.expense.ExpenseManufacturingManager;
import jp.co.dailyReport.CSVManager;

/**
 * 仕掛計上ページのボタン（計上、CSV出力）
 * が押されたときの処理を管理するクラスです。
 */
public class ExpenseManufacturingResultAction extends Action {

	private static Logger log = Logger.getLogger(ExpenseManufacturingResultAction.class);
	private static final int PAGE_COUNT = 30;
	private static final int PAGE_CSV_COUNT = 300;

	/**
	 * 仕掛計上ページのボタン（計上、CSV出力）が押されたときの処理を管理するクラスです。<BR><BR>
	 * 
	 * 「計上」ボタンが押された場合の処理：<BR>
	 * 仕掛計上条件の入力チェックを行います。
	 * 計上条件にあった計上結果を取得します。<BR><BR>
	 * 「CSV出力」ボタンが押された場合の処理：<BR>
	 * 仕掛計上条件の入力チェックを行います。
	 * 計上条件にあった計上結果をCSV形式ファイルに書き込み出力します。
	 * 
	 * @param mapping このインスタンスを選択するために使用したActionMapping
	 * @param form 存在するならば、このリクエストのためのActionForm Bean
	 * @param request 処理しているHTTPリクエスト
	 * @param response 処理しているHTTPレスポンス
	 * @return ActionForwardインスタンス
	 * @throws IOException, ServletException
	 */
	public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)
		 throws IOException, ServletException {

		log.debug("ExpenseManufacturingResultAction start");
		HttpSession session = request.getSession();
		log.debug("session.getId() = " + session.getId());
		Staff staff = (Staff)session.getAttribute("LoginStaff");
		DynaValidatorForm expenseManufacturingConditionActionForm = (DynaValidatorForm) form;
		ExpenseManufacturingResult[] expenseManufacturingResult = null;
		String target = null;
		ActionErrors errors = new ActionErrors();

		int customerId = ((Integer)expenseManufacturingConditionActionForm.get("customerId")).intValue();
		int projectId = ((Integer)expenseManufacturingConditionActionForm.get("projectId")).intValue();
		int staffId = ((Integer)expenseManufacturingConditionActionForm.get("staffId")).intValue();
		int startWorkDateYear = ((Integer)expenseManufacturingConditionActionForm.get("startWorkDateYear")).intValue();
		int startWorkDateMonth = ((Integer)expenseManufacturingConditionActionForm.get("startWorkDateMonth")).intValue();
		int startWorkDateDay = ((Integer)expenseManufacturingConditionActionForm.get("startWorkDateDay")).intValue();
		int endWorkDateYear = ((Integer)expenseManufacturingConditionActionForm.get("endWorkDateYear")).intValue();
		int endWorkDateMonth = ((Integer)expenseManufacturingConditionActionForm.get("endWorkDateMonth")).intValue();
		int endWorkDateDay = ((Integer)expenseManufacturingConditionActionForm.get("endWorkDateDay")).intValue();

		//仕掛計上条件情報設定
		ExpenseManufacturingCondition expenseManufacturingCondition = new ExpenseManufacturingCondition();
		expenseManufacturingCondition.setCustomerId(customerId);
		expenseManufacturingCondition.setProjectId(projectId);
		expenseManufacturingCondition.setStaffId(staffId);
		java.text.DateFormat df = new java.text.SimpleDateFormat("yyyyMMdd");
		int startWorkDate = 0;
		if(startWorkDateYear!=0 && startWorkDateMonth!=0 && startWorkDateDay!=0){
			Calendar cal = Utilities.getCalendarDate(startWorkDateYear,startWorkDateMonth,startWorkDateDay);
			expenseManufacturingCondition.setStartWorkDate(cal);
			startWorkDate = Integer.parseInt(df.format(cal.getTime()));
		}
		int endWorkDate = 0;
		if(endWorkDateYear!=0 && endWorkDateMonth!=0 && endWorkDateDay!=0){
			Calendar cal = Utilities.getCalendarDate(endWorkDateYear,endWorkDateMonth,endWorkDateDay);
			expenseManufacturingCondition.setEndWorkDate(cal);
			endWorkDate = Integer.parseInt(df.format(cal.getTime()));
		}

		//仕掛計上条件のチェック
		int conditionStatus = 0;
		if(customerId==0) conditionStatus++;
		if(projectId==0) conditionStatus++;
		if(staffId==0) conditionStatus++;
		if(startWorkDate==0) conditionStatus++;
		if(endWorkDate==0) conditionStatus++;

		//仕掛計上条件入力判定
		if(conditionStatus != ExpenseManufacturingCondition.CONDITION_STATUS){
			//仕掛計上期間条件判定
			if(startWorkDate > endWorkDate && endWorkDate != 0){
				target = "error";
				errors.add("errors.expense.expenseManufacturingCondition.invalid",new ActionError("errors.expense.expenseManufacturingCondition.invalid"));
				saveErrors(request,errors);
			} else {
				target = "result";
				//CSV出力
				if(request.getParameter("csv")!=null) {
					expenseManufacturingResultCSV(expenseManufacturingConditionActionForm,request,response,expenseManufacturingCondition);
					return null;
				//ブラウザ出力
				} else {
					expenseManufacturingResultList(expenseManufacturingConditionActionForm,request,expenseManufacturingCondition);
				}
			}
		}else{
			target = "error";
			errors.add("errors.expense.expenseManufacturingCondition.required",new ActionError("errors.expense.expenseManufacturingCondition.required"));
			saveErrors(request,errors);
		}

		log.debug("ExpenseManufacturingResultAction end");
		return mapping.findForward(target);
	}


	private void expenseManufacturingResultList(ActionForm form, HttpServletRequest request,ExpenseManufacturingCondition expenseManufacturingCondition) {

		HttpSession session = request.getSession();
		DynaValidatorForm expenseManufacturingConditionActionForm = (DynaValidatorForm) form;
		ExpenseManufacturingResult[] expenseManufacturingResult = null;
		Staff staff = (Staff)session.getAttribute("LoginStaff");
		try {
			//ﾍﾟｰｼﾞ刻み処理追加途中
			int pageId = 0;
			if(!((Integer)expenseManufacturingConditionActionForm.get("pageId")).equals("")){
				pageId = ((Integer)expenseManufacturingConditionActionForm.get("pageId")).intValue();
			}
			//総合計件数
			int numberOfAllresult = ((Integer)expenseManufacturingConditionActionForm.get("numberOfAllresult")).intValue();
			if(numberOfAllresult==0) {
				numberOfAllresult = ExpenseManufacturingManager.getExpenseManufacturingResultCount(staff,expenseManufacturingCondition);
				expenseManufacturingConditionActionForm.set("numberOfAllresult",new Integer(numberOfAllresult));
			}

			int maxPage = (numberOfAllresult  - 1) / PAGE_COUNT + 1;
			int start = PAGE_COUNT * pageId;
			int end = PAGE_COUNT * (pageId + 1);
			int nextNumber = numberOfAllresult - end;
			if(nextNumber > PAGE_COUNT){
				nextNumber = PAGE_COUNT;
			}
			expenseManufacturingCondition.setLimit(start,PAGE_COUNT);

			expenseManufacturingResult = ExpenseManufacturingManager.load(staff,expenseManufacturingCondition);
			int beforePageNumber = ((pageId +maxPage - 1 ) % maxPage);
			int nextPageNumber = ((pageId + 1) % maxPage) ;
			if(pageId == 0){
				request.setAttribute("back", "0");
			}
			if(pageId == maxPage -1){
				request.setAttribute("next", "0");
			}

			java.util.Map info = new java.util.HashMap();
			info.put("customerId",new Integer(expenseManufacturingCondition.getCustomerId()));
			info.put("projectId",new Integer(expenseManufacturingCondition.getProjectId()));
			info.put("staffId",new Integer(expenseManufacturingCondition.getStaffId()));
			info.put("startWorkDateYear",(Integer)expenseManufacturingConditionActionForm.get("startWorkDateYear"));
			info.put("startWorkDateMonth",(Integer)expenseManufacturingConditionActionForm.get("startWorkDateMonth"));
			info.put("startWorkDateDay",(Integer)expenseManufacturingConditionActionForm.get("startWorkDateDay"));
			info.put("endWorkDateYear",(Integer)expenseManufacturingConditionActionForm.get("endWorkDateYear"));
			info.put("endWorkDateMonth",(Integer)expenseManufacturingConditionActionForm.get("endWorkDateMonth"));
			info.put("endWorkDateDay",(Integer)expenseManufacturingConditionActionForm.get("endWorkDateDay"));
			info.put("numberOfAllresult",new Integer(numberOfAllresult));

			request.setAttribute("paramInfo", info);
			request.setAttribute("beforePageNumber", new Integer(beforePageNumber));                
			request.setAttribute("nextPageNumber", new Integer(nextPageNumber));
			request.setAttribute("displayPageNumber", new Integer(pageId+1));
			request.setAttribute("maxPage", new Integer(maxPage));
			request.setAttribute("backNumber", new Integer(PAGE_COUNT));
			request.setAttribute("nextNumber", new Integer(nextNumber));
			request.setAttribute("expenseManufacturingResult", expenseManufacturingResult);
		} catch(DataUnavailableException due) {
			log.error(due.getMessage());
		}
	}

	private void expenseManufacturingResultCSV(ActionForm form, HttpServletRequest request, HttpServletResponse response,ExpenseManufacturingCondition expenseManufacturingCondition) {

		HttpSession session = request.getSession();
		ExpenseManufacturingResult[] expenseManufacturingResult = null;
		Staff staff = (Staff)session.getAttribute("LoginStaff");
		try {
			//総合計件数
			int numberOfAllresult = ExpenseManufacturingManager.getExpenseManufacturingResultCount(staff,expenseManufacturingCondition);
			int maxPage = (numberOfAllresult  - 1) / PAGE_CSV_COUNT + 1;
				Vector vec = new Vector();
				for(int i = 0;i<maxPage;i++){
					expenseManufacturingCondition.setLimit(i*PAGE_CSV_COUNT,PAGE_CSV_COUNT);
					expenseManufacturingResult = ExpenseManufacturingManager.load(staff,expenseManufacturingCondition);
					for(int j = 0;j<expenseManufacturingResult.length;j++){
						vec.add(expenseManufacturingResult[j]);
					}
				}
				CSVManager.CSVOutput(response,(ExpenseManufacturingResult[])vec.toArray(new ExpenseManufacturingResult[0]));
		} catch(DataUnavailableException due) {
			log.error(due.getMessage());
		}
	}
}
